//! 互联网相关数据生成器模块

use rand::seq::SliceRandom;
use rand::Rng;

/// 邮箱域名
const EMAIL_DOMAINS: &[&str] = &[
    "gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "qq.com",
    "163.com", "126.com", "sina.com", "sohu.com", "example.com"
];

/// 顶级域名
const TLDS: &[&str] = &[
    "com", "org", "net", "edu", "gov", "mil", "int", "cn", "uk", "de", "fr", "jp"
];

/// 用户代理字符串
const USER_AGENTS: &[&str] = &[
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
];

/// 生成邮箱地址
pub fn email() -> String {
    let mut rng = rand::thread_rng();
    let username_len = rng.gen_range(5..=15);
    let username: String = (0..username_len)
        .map(|_| {
            let chars = b"abcdefghijklmnopqrstuvwxyz0123456789";
            chars[rng.gen_range(0..chars.len())] as char
        })
        .collect();
    
    let domain = EMAIL_DOMAINS.choose(&mut rng).unwrap();
    format!("{}@{}", username, domain)
}

/// 生成用户名
pub fn username() -> String {
    let mut rng = rand::thread_rng();
    let len = rng.gen_range(6..=20);
    (0..len)
        .map(|_| {
            let chars = b"abcdefghijklmnopqrstuvwxyz0123456789_";
            chars[rng.gen_range(0..chars.len())] as char
        })
        .collect()
}

/// 生成密码
pub fn password(length: usize) -> String {
    let mut rng = rand::thread_rng();
    let chars = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
    (0..length)
        .map(|_| chars[rng.gen_range(0..chars.len())] as char)
        .collect()
}

/// 生成强密码（包含大小写字母、数字和特殊字符）
pub fn strong_password() -> String {
    let mut rng = rand::thread_rng();
    let length = rng.gen_range(12..=20);
    
    let mut password = String::new();
    
    // 确保至少包含一个大写字母
    password.push(('A'..='Z').nth(rng.gen_range(0..26)).unwrap());
    
    // 确保至少包含一个小写字母
    password.push(('a'..='z').nth(rng.gen_range(0..26)).unwrap());
    
    // 确保至少包含一个数字
    password.push(('0'..='9').nth(rng.gen_range(0..10)).unwrap());
    
    // 确保至少包含一个特殊字符
    let special_chars = "!@#$%^&*";
    password.push(special_chars.chars().nth(rng.gen_range(0..special_chars.len())).unwrap());
    
    // 填充剩余长度
    let all_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
    for _ in 4..length {
        password.push(all_chars.chars().nth(rng.gen_range(0..all_chars.len())).unwrap());
    }
    
    // 打乱字符顺序
    let mut chars: Vec<char> = password.chars().collect();
    chars.shuffle(&mut rng);
    chars.into_iter().collect()
}

/// 生成域名
pub fn domain() -> String {
    let mut rng = rand::thread_rng();
    let name_len = rng.gen_range(5..=15);
    let name: String = (0..name_len)
        .map(|_| {
            let chars = b"abcdefghijklmnopqrstuvwxyz";
            chars[rng.gen_range(0..chars.len())] as char
        })
        .collect();
    
    let tld = TLDS.choose(&mut rng).unwrap();
    format!("{}.{}", name, tld)
}

/// 生成URL
pub fn url() -> String {
    let mut rng = rand::thread_rng();
    let protocols = ["http", "https"];
    let protocol = protocols.choose(&mut rng).unwrap();
    let domain = domain();
    let path_len = rng.gen_range(0..=3);
    
    let mut url = format!("{}://{}", protocol, domain);
    
    for _ in 0..path_len {
        let segment_len = rng.gen_range(3..=10);
        let segment: String = (0..segment_len)
            .map(|_| {
                let chars = b"abcdefghijklmnopqrstuvwxyz0123456789";
                chars[rng.gen_range(0..chars.len())] as char
            })
            .collect();
        url.push('/');
        url.push_str(&segment);
    }
    
    url
}

/// 生成IP地址
pub fn ip_address() -> String {
    let mut rng = rand::thread_rng();
    format!(
        "{}.{}.{}.{}",
        rng.gen_range(1..=255),
        rng.gen_range(0..=255),
        rng.gen_range(0..=255),
        rng.gen_range(1..=254)
    )
}

/// 生成IPv6地址
pub fn ipv6_address() -> String {
    let mut rng = rand::thread_rng();
    (0..8)
        .map(|_| format!("{:04x}", rng.gen_range(0..=0xffff)))
        .collect::<Vec<_>>()
        .join(":")
}

/// 生成MAC地址
pub fn mac_address() -> String {
    let mut rng = rand::thread_rng();
    (0..6)
        .map(|_| format!("{:02x}", rng.gen_range(0..=255)))
        .collect::<Vec<_>>()
        .join(":")
}

/// 生成IPv4地址（别名）
pub fn ipv4() -> String {
    ip_address()
}

/// 生成IPv6地址（别名）
pub fn ipv6() -> String {
    ipv6_address()
}

/// 生成默认长度密码
pub fn default_password() -> String {
    password(12)
}

/// 生成用户代理字符串
pub fn user_agent() -> String {
    let mut rng = rand::thread_rng();
    USER_AGENTS.choose(&mut rng).unwrap().to_string()
}

/// 生成端口号
pub fn port() -> u16 {
    let mut rng = rand::thread_rng();
    rng.gen_range(1024..=65535)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_email() {
        let email = email();
        assert!(email.contains('@'));
        assert!(email.contains('.'));
    }

    #[test]
    fn test_strong_password() {
        let password = strong_password();
        assert!(password.len() >= 12);
        assert!(password.chars().any(|c| c.is_uppercase()));
        assert!(password.chars().any(|c| c.is_lowercase()));
        assert!(password.chars().any(|c| c.is_ascii_digit()));
        assert!(password.chars().any(|c| "!@#$%^&*".contains(c)));
    }

    #[test]
    fn test_ip_address() {
        let ip = ip_address();
        let parts: Vec<&str> = ip.split('.').collect();
        assert_eq!(parts.len(), 4);
        
        for part in parts {
            let num: u16 = part.parse().unwrap();
            assert!(num <= 255);
        }
    }

    #[test]
    fn test_mac_address() {
        let mac = mac_address();
        let parts: Vec<&str> = mac.split(':').collect();
        assert_eq!(parts.len(), 6);
        
        for part in parts {
            assert_eq!(part.len(), 2);
            assert!(u8::from_str_radix(part, 16).is_ok());
        }
    }
}